use actix_cors::Cors;
use actix_web::{
    App, HttpServer,
    middleware::{self, Logger},
    web,
};
use api_server::{models::SharedData, views};
use log::{Level, info};

const SERVER_PORT: u16 = 8080;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

    info!("starting HTTP server at http://localhost:8080");

    let shared = web::Data::new(SharedData::default());

    HttpServer::new(move || {
        let cors = Cors::default()
            .allowed_origin("http://127.0.0.1:3000")
            .allowed_origin("http://localhost:3000")
            .allowed_methods(vec!["GET", "POST"])
            .allowed_headers(vec![
                "Access-Control-Allow-Headers",
                "Authorization",
                "authorization",
                "X-Requested-With",
                "Content-Type",
                "content-type",
                "Origin",
                "Client-id",
                "user-agent",
                "User-Agent",
                "Accept",
                "Referer",
                "referer",
                "Nonce",
                "signature",
                "Timestamp",
                "AppKey",
                "x-super-properties",
                "X-Super-Properties",
            ])
            .max_age(3600);

        App::new()
            .wrap(cors)
            // enable logger - always register Actix Web Logger middleware last
            .wrap(middleware::Logger::log_level(
                Logger::default(),
                Level::Info,
            ))
            .service(
                web::scope("/api").service(
                    web::scope("/v1")
                        .service(
                            web::scope("/client")
                                .app_data(shared.clone())
                                .service(views::client::status)
                                .service(views::client::launch)
                                .service(views::client::stop),
                        )
                        .service(
                            web::scope("/device")
                                .app_data(shared.clone())
                                .service(views::device::register)
                                .service(views::device::status),
                        ),
                ),
            )
    })
    .bind(("127.0.0.1", SERVER_PORT))?
    .run()
    .await
}
